package org.learning;

import java.util.concurrent.*;

/**
 * 线程创建方法
 * <p>
 * java中有两种线程：守护线程和非守护线程
 * 一般创建的线程都是非守护线程，除非手动setDaemon为true。
 * GC线程是守护线程。
 * 只有所有非守护线程结束运行，jvm才会终止运行（java程序结束）
 * <p>
 * 线程有以下状态：
 * NEW
 * RUNNABLE
 * BLOCKED
 * WAITING
 * TIME_WAITING
 * TERMINATED
 */
public class A_02 {
    /**
     * 线程创建方法1
     */
    private static class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(getName() + "运行了。。。");
                try {
                    Thread.sleep(800);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 线程创建方法2
     */
    private static class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("实现接口的线程。。。");
        }
    }

    /**
     * 线程创建方法3
     */
    private static class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            Thread.sleep(5000);
            return "呵呵";
        }
    }

    private static class MyCallable2 implements Callable<String> {
        @Override
        public String call() throws Exception {
            int i = 1 / 0;
            Thread.sleep(i);
            return "呵呵2";
        }
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5, 10,
                1, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(10)
        ) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                //如果在call方法执行过程中有错误，则可以在此做处理
                System.out.println("处理了错误。。。");
            }
        };

        Future<String> submitFuture = threadPoolExecutor.submit(new MyCallable2());
//        String futStr = submitFuture.get();
//        System.out.println(futStr);

        MyThread myThread = new MyThread();
        myThread.start();

        new Thread(new MyRunnable()).start();

        FutureTask<String> futureTask = new FutureTask<String>(new MyCallable());
        new Thread(futureTask).start();
        System.out.println(futureTask.get());
        myThread.join();



        System.out.println(Thread.currentThread().getName() + "运行起来了。。");
    }
}
